package test;

import java.awt.BorderLayout;
import java.awt.FileDialog;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.filechooser.FileSystemView;

public class PicEdit extends JFrame{
	private int currentPixArray[] = null;// 保存当前操作的像素矩阵 
    BufferedImage bufImage = null;  //用于显示的缓冲区图像 
    BufferedImage originalBufImage;  //原始缓冲区图像 
    private String lastDir = "";// 图像的路径 
    private JLabel imageLabel = null;// 用于显示图像的标签 
    private BufferedImage newImage;// 加载的图像 
    private int h, w;// 图像的高和宽 
    private LinkedList<int[]> imageStack = new LinkedList<int[]>();// 保存历史操作图像矩阵 
    private LinkedList<int[]> tempImageStack = new LinkedList<int[]>();
    
    
    public PicEdit() { 
        super("图片特效工具"); 

        // 创建菜单 
        JToolBar toolBar = new JToolBar(); 
        this.add(toolBar,BorderLayout.NORTH); 
        //skin sk = new skin(); 
        JButton openbutton = new JButton(new ImageIcon("sk.getAddpic()")); 
        //JButton exitbutton = new JButton(new ImageIcon("sk.getExit()")); 
        //JButton graybutton = new JButton(new ImageIcon("sk.getGray()")); 
        //JButton balancebutton = new JButton(new ImageIcon("sk.getBalance()")); 
		JButton blurbutton = new JButton(new ImageIcon("sk.getBlur()")); 
		JButton sharpenbutton = new JButton(new ImageIcon("sk.getSharpen()")); 
		JButton resetbutton = new JButton(new ImageIcon("sk.getReset()")); 
		JButton backbutton = new JButton(new ImageIcon("sk.getPrevious()")); 
		JButton frontbutton = new JButton(new ImageIcon("sk.getNext()")); 
		//JButton waterbutton = new JButton(new ImageIcon("sk.getWater()")); 
		//JButton spotlightbutton = new JButton(new ImageIcon("sk.getSpotlight()")); 
		//JButton bitbltbutton = new JButton(new ImageIcon("sk.getBiblt()")); 
		//JButton printscbutton = new JButton(new ImageIcon("sk.getPrintsc()")); 
		JButton savebutton = new JButton(new ImageIcon("sk.getSave()")); 

		openbutton.setToolTipText("打开文件"); 
		openbutton.setText("打开文件"); 
		openbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);//让文字置于图标 
		openbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);//下方 
		openbutton.addActionListener(new OpenListener()); 

		blurbutton.setToolTipText("模糊"); 
		blurbutton.setText("模糊"); 
		blurbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		blurbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		blurbutton.addActionListener(new BlurActionListener()); 

		sharpenbutton.setToolTipText("锐化"); 
		sharpenbutton.setText("锐化"); 
		sharpenbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		sharpenbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		sharpenbutton.addActionListener(new SharpenActionListener()); 

		resetbutton.setToolTipText("还原"); 
		resetbutton.setText("还原"); 
		resetbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		resetbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		resetbutton.addActionListener(new ResetMenuItemActionListener()); 

		backbutton.setToolTipText("后退"); 
		backbutton.setText("后退"); 
		backbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		backbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		backbutton.addActionListener(new BackActionListener()); 

		frontbutton.setToolTipText("前进"); 
		frontbutton.setText("前进"); 
		frontbutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		frontbutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		frontbutton.addActionListener(new FrontActionListener()); 

		savebutton.setToolTipText("保存图片到桌面"); 
		savebutton.setText("保存"); 
		savebutton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
		savebutton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); 
		savebutton.addActionListener(new SaveListener()); 

		toolBar.add(openbutton); 
		toolBar.add(blurbutton); 
		toolBar.add(sharpenbutton); 
		toolBar.add(backbutton); 
		toolBar.add(frontbutton); 
		toolBar.add(resetbutton); 
		toolBar.add(savebutton); 
	
		this.setSize(1200,700); 
		this.setLocation(20,20); 
		this.setVisible(true); 
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

        imageLabel = new JLabel(""); 
        JScrollPane pane = new JScrollPane(imageLabel); 
        this.add(pane, BorderLayout.CENTER); 

        this.setVisible(true); 
    } 
    
    
    //-----------------菜单监听器---------------// 
    private class OpenListener implements ActionListener { 
    	public void actionPerformed(ActionEvent e) { 
        	FileDialog d = new FileDialog(PicEdit.this,"Open image file",FileDialog.LOAD); 
            d.setFile(".jpg"); 
            d.setDirectory(lastDir); 
            d.setVisible(true); 
            String file = d.getFile(); 
            lastDir = d.getDirectory(); 
            if(file!=null){ 
            try { 
                    newImage = ImageIO.read(new File(lastDir+file)); 
                    originalBufImage = newImage; 
                    w = newImage.getWidth(); 
                    h = newImage.getHeight(); 
                    currentPixArray = getPixArray(newImage, w, h); 
                    imageStack.clear(); 
                    tempImageStack.clear(); 
                    imageStack.addLast(currentPixArray); 
                    imageLabel.setIcon(new ImageIcon(newImage)); 

                } catch (IOException ex) { 
                    System.out.println(ex); 
                } 
            } 
            PicEdit.this.repaint(); 
        } 
    } 

    private class BackActionListener implements ActionListener { 
        public void actionPerformed(ActionEvent e) { 
            if (imageStack.size() <= 1) { 
                JOptionPane.showMessageDialog(null, "此幅图片的处理已经没有后退历史操作了", "提示", 
                        JOptionPane.INFORMATION_MESSAGE); 
            } else { 
                tempImageStack.addLast(imageStack.removeLast()); 
                currentPixArray = imageStack.getLast(); 
                showImage(currentPixArray); 
                PicEdit.this.setRGB(newImage,0,0,w,h,currentPixArray);//将变换后的结果保存到newImage里 
            } 
        }
    } 

    private class FrontActionListener implements ActionListener { 
        public void actionPerformed(ActionEvent e) { 
            if (tempImageStack.size() < 1) { 
                JOptionPane.showMessageDialog(null, "此幅图片的处理已经没有前进历史操作了", "提示", 
                        JOptionPane.INFORMATION_MESSAGE); 
            } else { 
                currentPixArray = tempImageStack.removeFirst(); 
                imageStack.addLast(currentPixArray); 
                showImage(currentPixArray); 
                PicEdit.this.setRGB(newImage,0,0,w,h,currentPixArray); 
            } 
        } 

    } 
    
    private class BlurActionListener implements ActionListener{ 
	    public void actionPerformed(ActionEvent e){ 
	    	PicEdit.this.blur(); 
	    } 
    } 

    private class SharpenActionListener implements ActionListener{ 
    	public void actionPerformed(ActionEvent e){ 
    		PicEdit.this.sharpen(); 
    	} 
    } 
    
    private class ResetMenuItemActionListener implements ActionListener{ 
    	public void actionPerformed(ActionEvent e){ 
    		PicEdit.this.reset(); 
    	} 
    } 
    

   private class SaveListener implements ActionListener{ 
	   public void actionPerformed(ActionEvent e){ 
		   save(); 
	   } 
    } 
   
   	//-----------------过滤图像---------------// 
    public void applyFilter(float[] data) { 
    	if (newImage == null) 
    		return; //如果newImage为空则直接返回 
    		Kernel kernel = new Kernel(3, 3, data); 
    		ConvolveOp imageOp=new ConvolveOp(kernel,ConvolveOp.EDGE_NO_OP, null); //创建卷积变换操作对象 
    		BufferedImage filteredBufImage = new BufferedImage(newImage.getWidth(PicEdit.this),newImage.getHeight(PicEdit.this),BufferedImage.TYPE_INT_ARGB); //过滤后的缓冲区图像 
    		imageOp.filter(newImage, filteredBufImage);//过滤图像，目标图像在filteredBufImage 
    		newImage = filteredBufImage; //让用于显示的缓冲区图像指向过滤后的图像 
    		int[] resultArray = getPixArray(newImage, w, h); 
    		imageStack.addLast(resultArray); 
    		currentPixArray = resultArray; 
    		showImage(resultArray); 
    		tempImageStack.clear(); 
    		PicEdit.this.setRGB(newImage,0,0,w,h,resultArray); 
    } 
    
    //-----------------模糊图像---------------// 
    public void blur() { 
    	if (newImage == null) 
    		return; 
    	float[] data = { 
    			0.0625f, 0.125f, 0.0625f, 
    			0.125f, 0.025f, 0.125f, 
    			0.0625f, 0.125f, 0.0625f 
    	}; 
    	applyFilter(data); 
    } 
       
  //-----------------锐化图像---------------// 
    public void sharpen() { 
       if (newImage == null) 
        return; 
       float[] data = { 
               -1.0f, -1.0f, -1.0f, 
               -1.0f, 9.0f, -1.0f, 
               -1.0f, -1.0f, -1.0f 
       }; 
       applyFilter(data); 
      } 
        
    //-----------------还原图像---------------// 
    public void reset() { 
       if (newImage == null) 
        return; 
       int[] resultArray = imageStack.getFirst(); 
   imageStack.addLast(resultArray); 
   currentPixArray = resultArray; 
   showImage(resultArray); 
   tempImageStack.clear(); 
   PicEdit.this.setRGB(newImage,0,0,w,h,resultArray); 
      } 
    
  //-----------------获取图像像素矩阵---------------// 
    private int[] getPixArray(Image im, int w, int h) { 
        int[] pix = new int[w * h]; 
        PixelGrabber pg = null; 
        try { 
            pg = new PixelGrabber(im, 0, 0, w, h, pix, 0, w); 
            if (pg.grabPixels() != true) 
                try { 
                    throw new java.awt.AWTException("pg error" + pg.status()); 
                } catch (Exception eq) { 
                    eq.printStackTrace(); 
                } 
        } catch (Exception ex) { 
            ex.printStackTrace(); 

        } 
        return pix; 
    } 

  //-----------------显示图片---------------// 
    private void showImage(int[] srcPixArray) { 
        Image pic = createImage(new MemoryImageSource(w, h, srcPixArray, 0, w)); 
        ImageIcon ic = new ImageIcon(pic); 
        imageLabel.setIcon(ic); 
        imageLabel.repaint(); 
    } 
   
  //-----------------将图像数组转变成BufferedImage图像---------------// 
    public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) { 
	int type = image.getType(); 
	if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB ) 
	image.getRaster().setDataElements( x, y, width, height, pixels ); 
	else 
	image.setRGB( x, y, width, height, pixels, 0, width ); 
    } 
    
  //-----------------保存图像到桌面---------------// 
    public void save(){ 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyymmddHHmmss"); 
        String name = sdf.format(new Date()); 
        File path = FileSystemView.getFileSystemView().getHomeDirectory(); 
        String format = "jpg"; 
        File f = new File(path + File.separator + name + "." + format); 
        try { 
            ImageIO.write(newImage, format, f); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
    } 
    
    public static void main(String[] args){ 
    new PicEdit(); 
    } 

}
